﻿using System;
using System.Collections.Generic;
using Zeta.Bot;
using Zeta.Common;

namespace KadalaSpree.XCore
{
    /// <summary>
    /// Handles common event logic, debouncing and distributing events to modules
    /// </summary>
    public class XModules
    {
        private readonly List<XModule> _modules = new List<XModule>();

        internal List<XModule> Modules
        {
            get { return _modules; }
        }

        public void Register (XModule module, XPlugin plugin)
        {
            module.Plugin = plugin;

            if (!_modules.Contains(module))
                _modules.Add(module);
        }

        public void Unsubscribe (XModule module)
        {
            if (_modules.Contains(module))
                _modules.Remove(module);
        }

        public void Pulse()
        {
            DateTime pulseTime = DateTime.UtcNow;
            foreach (var module in _modules)
            {
                if (pulseTime.Subtract(module.LastPulse).TotalMilliseconds > module.DebounceInterval)
                {
                    module.DebouncedPulse();
                    module.LastPulse = DateTime.UtcNow;
                }
                module.Pulse();
            }
        }

        public void OnEnabled()
        {
            BotMain.OnStart += OnStart;
            BotMain.OnStop += OnStop;
            GameEvents.OnGameChanged += OnGameChanged;
            TreeHooks.Instance.OnHooksCleared += X.Hooks.Instance_OnHooksCleared;

            _modules.ForEach(module =>
            {
                module.OnEnabled();
                X.Logger.Instance.Log("{0} Enabled!", module.Name);
            });
        }

        public void OnGameChanged (object sender, EventArgs e)
        {
            _modules.ForEach(module => module.OnGameChanged());
        }

        public void OnInitialize()
        {
            _modules.ForEach(module =>
            {
                module.BaseInitialize();
                module.OnInitialize();
                X.Logger.Instance.Log("{0} Initialized!", module.Name);
            });
        }

        public void OnDisabled()
        {
            BotMain.OnStart -= OnStart;
            BotMain.OnStop -= OnStop;
            GameEvents.OnGameChanged -= OnGameChanged;
            TreeHooks.Instance.OnHooksCleared -= X.Hooks.Instance_OnHooksCleared;
            X.Hooks.RemoveHooks();

            _modules.ForEach(module =>
            {
                module.OnDisabled();
                X.Logger.Instance.Log("{0} Disabled!", module.Name);
            });
        }

        public void OnShutdown()
        {
            _modules.ForEach(module =>
            {
                module.OnShutdown();
                X.Logger.Instance.Log("{0} Shutdown!", module.Name);
            });
        }

        public void OnStart (IBot bot)
        {
            X.Hooks.InsertHooks();
            _modules.ForEach(module => module.OnStart());
        }

        public void OnStop (IBot bot)
        {
            _modules.ForEach(module => module.OnStop());
        }
    }
}